package family

import (
	"io/ioutil"
	"encoding/json"
	"errors"
	"fmt"
	"homeserver/logs"
)

// 家庭成员信息
type MemberInfo  struct {
	Id 		string		`json:"id"`
	Key 	string		`json:"key"`
	Name 	string		`json:"name"`
	Icon 	string 		`json:"icon"`
}

// 家庭设备基本信息
type DeviceInfo struct {
	Id 		string		`json:"id"`
	Desc 	string		`json:"desc"`
}

// 家庭信息
type Family struct {
	Name 		string		`json:"name"`
	Id 			string		`json:"id"`
	Message 	string		`json:"message"`

	Members		[]*MemberInfo	`json:"members"`
	Devices 	[]*DeviceInfo	`json:"devices"`
}

//
// 处理设备事件
// devId: 设备ID
// state: 设备状态 [login, logout]
//
func (f *Family) handleNotifyDev(devId , state string) (err error) {
	err = errors.New("404")
	if state != NOTIFY_DEV_LOGOUT {
		return nil
	}

	logs.Info("family device logout")

	dev, ok := DevicesMap[devId]
	if !ok {
		return err
	}

	dev.Offline()

	post := &FamilyNotifyInfo{}

	// 通知所有连接的终端
	for _, mem := range f.Members {
		for _, sev := range dev.Services {
			post.DevId = dev.Id
			post.SevId = sev.Id
			post.State = sev.State.Type
			post.Desc = sev.State.Desc
			// 发送出去
			f.notifyMember(mem.Id, post)
		}
	}

	return nil
}

//
// 设备服务状态改变事件
// devId: 设备ID
// sevId: 服务ID
// state: 状态类型[open close offline online ...]
// t: 状态改变的原因 [result state hand]
//
func (f *Family) handleNotifySev(devId, sevId, notify_t string, data interface{}) (err error) {
	err = errors.New("404")
	// 找到设备
	dev, ok := DevicesMap[devId]
	if !ok {
		return
	}

	sev_t, err := dev.GetSevType(sevId)
	if err != nil {
		return
	}

	if sev_t == NOTIFY_SEV_TEMP_T {
		return f.handleNotifyTemp(dev, sevId, notify_t, data)
	}

	if sev_t == NOTIFY_SEV_SWITCH_T {
		return f.handleNotifySwitch(dev, sevId, notify_t, data)
	}

	return nil
}

// 家庭温湿度描述信息
type FamilyTempInfo struct {
	Temperate 	float32		`json:"temp"`
	Humidity 	float32		`json:"humd"`
}

//
// 处理温湿度服务
//
func (f *Family) handleNotifyTemp(dev *DeviceCell, sevId string, notify_t string, data interface{}) (err error) {
	//
	err = dev.SetSevState(sevId, notify_t)
	if err != nil {
		return
	}

	// 获取服务信息
	info, err := dev.GetSevState(sevId)
	if err != nil {
		return
	}

	buf, err := json.Marshal(data)
	if err != nil {
		return
	}

	var temp FamilyTempInfo
	err = json.Unmarshal(buf, &temp)
	if err != nil {
		return
	}

	post := &FamilyNotifyInfo{
		DevId: dev.Id,
		SevId: sevId,
		State: info.Type,
	}

	post.Desc = fmt.Sprintf("%0.1f℃ - %0.0f%%", temp.Temperate, temp.Humidity)
	for _, mem := range f.Members {
		f.notifyMember(mem.Id, post)
	}

	dev.SetSevStateDesc(sevId, post.Desc)

	post_hint := &FamilyNotifyInfo{
		SevId: NOTIFY_SEV_FAMILY_MSG,
		State: NOTIFY_SEV_FAMILY_MSG_INFO,
	}
	post_hint.Desc = fmt.Sprintf("家里温度:%0.1f℃ 相对湿度:%0.0f%%", temp.Temperate, temp.Humidity)
	for _, mem := range f.Members {
		f.notifyMember(mem.Id, post_hint)
	}

	f.Message = post_hint.Desc

	return nil
}

//
// 处理开关服务通知
//
func (f *Family) handleNotifySwitch(dev *DeviceCell, sevId, notify_t string, data interface{}) (err error) {

	state, ok := data.(string)
	if !ok {
		return errors.New("404")
	}

	err = dev.SetSevState(sevId, state)
	if err != nil {
		return
	}

	info, err := dev.GetSevState(sevId)
	if err != nil {
		return
	}

	post := &FamilyNotifyInfo{
		DevId: dev.Id,
		SevId: sevId,
		State: info.Type,
		Desc: info.Desc,
	}

	post_hint := &FamilyNotifyInfo{
		SevId: NOTIFY_SEV_FAMILY_MSG,
		State: NOTIFY_SEV_FAMILY_MSG_INFO,
	}

	for _, mem := range f.Members {
		f.notifyMember(mem.Id, post)
	}

	if notify_t == "state" {
		return
	}

	desc, _ := dev.GetSevDesc(sevId)
	post_hint.Desc = "["+ desc.Major+"-"+ desc.Minor+"]"

	if notify_t == "hand" {
		post_hint.Desc += " 被手动"
	} else if notify_t == "result" {
		post_hint.Desc += " 被 光头云 通过手机"
	}

	if post.State == "open" {
		post_hint.Desc += "打开"
	} else {
		post_hint.Desc += "关闭"
	}

	for _, mem := range f.Members {
		f.notifyMember(mem.Id, post_hint)
	}

	return nil
}


//
// 处理来自家庭成员的请求操作
//
func (f *Family) handleRequestSev(memId string, devId string, sevId string, operate string) (err error){
	return nil
}

//
// 家消息打包通知给家庭成员
//
func (f *Family) notifyMember(memId string, info *FamilyNotifyInfo)  {
	notify_packet := FamilyNotifyPacket{
		MemId: memId,
		Data: info,
	}

	packet, err := json.Marshal(notify_packet)
	if err == nil {
		notifyMembers(packet)
	}
}


//
// 家庭成员向家庭请求 家庭所有的服务信息
//
func RequestSevAll(memId string, rev chan []byte) (err error) {
	// 通过成员ID找到对应的家庭
	err = errors.New("404")
	f, ok := MemFamilyMap[memId]
	if !ok {
		return
	}

	// 家庭消息
	post_hint := &FamilyNotifyInfo{
		SevId: NOTIFY_SEV_FAMILY_MSG,
		State: NOTIFY_SEV_FAMILY_MSG_INFO,
		Desc: f.Message,
	}

	buffer, _ := json.Marshal(post_hint)
	if rev != nil {
		rev <- buffer
	}

	// 遍历家庭设备列表
	for _, d := range f.Devices {

		dev, ok := DevicesMap[d.Id]
		if !ok {
			continue
		}

		// 装在服务描述信息，扔进通道
		for _, sev := range dev.Services {
			post := &FamilyNotifyInfo{
				DevId: dev.Id,
				SevId: sev.Id,
				State: sev.State.Type,
				Desc: sev.State.Desc,
			}

			buffer, _ := json.Marshal(post)
			if rev != nil {
				rev <- buffer
			} else {
				return err
			}
		}
	}

	return nil
}


var (
	family_conf_file = "conf/family.json"

	family_logger_file = "running/family_logger.txt"

	familyLogger  *logs.Logger
)

// 家庭成员ID 与 家庭对应的表
var FamilyMap = make(map[string]*Family)

// 设备ID 家庭 对应表
var DevFamilyMap = make(map[string]*Family)

// 家庭成员ID 与家庭对应列表
var MemFamilyMap = make(map[string]*Family)

//
// 初始化日志文件
//
func init() {
	familyLogger = logs.NewLogger(family_logger_file)
}

//
// 设备ID 家庭对应表
//
func FamilyConf() error {
	// 读取配置信息
	buf, err := ioutil.ReadFile(family_conf_file)
	if err != nil {
		return err
	}

	var familys []*Family
	err = json.Unmarshal(buf, &familys)
	if err != nil {
		return err
	}

	// 家庭家庭ID与家庭列表
	for _, f := range familys {
		FamilyMap[f.Id] = f
		// 设备 - 家庭表
		for _, dev := range f.Devices {
			DevFamilyMap[dev.Id] = f
		}
		// 成员 - 家庭表
		for _, mem := range f.Members {
			MemFamilyMap[mem.Id] = f
		}
	}

	return nil
}






